﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Pata.SylkSharp.Core.Bll
{
    /// <summary>
    /// Enumerates the possible fields in a <see cref="CRecord"/>
    /// </summary>
    public enum CRecordFieldType
    {
        /// <summary>
        /// X column
        /// column position (one based)
        /// </summary>
        X,
        /// <summary>
        /// Y row
        /// row position (one based)
        /// </summary>
        Y,
        /// <summary>
        /// E expression
        /// expression for the cell
        /// </summary>
        E,
        /// <summary>
        /// K value
        /// value of the cell
        /// </summary>
        K,
        /// <summary>
        /// C column
        /// column reference
        /// </summary>
        C,
        /// <summary>
        /// R row
        /// row reference
        /// </summary>
        R,
        /// <summary>
        /// defines shared value
        /// </summary>
        G,
        /// <summary>
        /// defines shared expression
        /// </summary>
        D,
        /// <summary>
        /// references shared value or shared expression
        /// </summary>
        S,
        /// <summary>
        /// If present, the cell is not protected.
        /// If absent and ;N is present in the ID record, cell is protected.
        /// </summary>
        N,
        /// <summary>
        /// If present, cell is protected.
        /// If absent and ;N is absent in the ID record, cell is not protected.
        /// </summary>
        P,
        /// <summary>
        /// If present, cell is hidden.
        /// If absent, cell is not hidden.
        /// </summary>
        H,
        /// <summary>
        /// M expression
        /// matrix expression from (X,Y) to (C,R)
        /// </summary>
        M,
        /// <summary>
        /// I
        /// inside a matrix
        /// </summary>
        I,
        /// <summary>
        /// Unknown field type.
        /// </summary>
        Unknown = 100
    }

    /// <summary>
    /// Object representation of field of a Sylk record of type 'C'
    /// </summary>
    public class CRecordField : FieldBase<CRecordFieldType>
    {
        /// <summary>
        /// Instanciate a new <see cref="CRecordField"/>
        /// </summary>
        public CRecordField()
            : base(CRecordFieldType.Unknown, String.Empty) { }

        /// <summary>
        /// Instanciate a new <see cref="CRecordField"/>
        /// </summary>
        /// <param name="pType">Type of this field.</param>
        /// <param name="pValue">The value contained by this field.</param>
        public CRecordField(CRecordFieldType pType, string pValue)
            : base(pType, pValue) { }
    }

    /// <summary>
    /// Object representation of a Sylk record of type 'C'.
    /// Cell contents
    /// </summary>
    public class CRecord : RecordBase<CRecordField, CRecordFieldType>
    {
        private static readonly CRecordFieldType[] _MANDATORY_FIELDS = 
            new CRecordFieldType[] { CRecordFieldType.X, CRecordFieldType.Y };

        /// <summary>
        /// Instanciate a new <see cref="CRecord"/>
        /// </summary>
        public CRecord(string pLineWithoutId)
            : base(RecordType.C, pLineWithoutId, CRecordFieldType.Unknown) { }

        /// <summary>
        /// Get mandatory fields for this record.
        /// </summary>
        /// <returns></returns>
        public override System.Collections.Generic.IEnumerable<CRecordFieldType> GetMandatoryFields()
        {
            return _MANDATORY_FIELDS;
        }

        /// <summary>
        /// Get the default field type.
        /// </summary>
        /// <returns></returns>
        public override CRecordFieldType GetUnknownFieldType()
        {
            return CRecordFieldType.Unknown;
        }
    }
}
